package mapper

import (
	"context"
	"gorm.io/gorm"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/initialize/mysql"
	"mall/services/product/rpc/internal/mapper/entity"
)

var attrValAllColumn = "attr_value_id, create_time, update_time, attr_id, value"

type AttrValueMapper struct {
	ctx context.Context
}

func NewAttrValueMapper(ctx context.Context) *AttrValueMapper {
	return &AttrValueMapper{ctx: ctx}
}

func (m *AttrValueMapper) SelectCountCtx(db *gorm.DB, attrValueBO bo.AttrValueBO) (totalCount int64, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrMapper#SelectCountCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})

	var total int64
	attrValueEntity := entity.AttrValueEntity{}
	tx = tx.Select(attrValAllColumn).Table(attrValueEntity.TableName())
	m.getAllWhereSql(tx, attrValueBO)
	tx.Count(&total)
	return total, tx.Error
}

func (m *AttrValueMapper) SelectOneCtx(db *gorm.DB, attrBO bo.AttrValueBO) (returnEntity entity.AttrValueEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#SelectOneCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})

	attrEntity := entity.AttrValueEntity{}
	tx = tx.Select(attrValAllColumn).Table(attrEntity.TableName())
	m.getAllWhereSql(tx, attrBO)
	tx.First(&attrEntity)
	if tx.Error == nil || tx.Error.Error() == "record not found" {
		return attrEntity, nil
	}
	return attrEntity, tx.Error
}

func (m *AttrValueMapper) SelectListCtx(db *gorm.DB, attrBO bo.AttrValueBO) (returnEntity []entity.AttrValueEntity, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#SelectListCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := db.Session(&gorm.Session{SkipDefaultTransaction: true})
	var attrValueEntityArr []entity.AttrValueEntity
	tx = tx.Select(attrValAllColumn).Table("attr_value")
	m.getAllWhereSql(tx, attrBO)
	tx = tx.Find(&attrValueEntityArr)
	return attrValueEntityArr, tx.Error
}

func (m *AttrValueMapper) getAllWhereSql(db *gorm.DB, valueBO bo.AttrValueBO) {
	if valueBO.AttrValueId > 0 {
		db.Where("attr_value_id = ?", valueBO.AttrValueId)
	}
	if valueBO.AttrId > 0 {
		db.Where("attr_id = ?", valueBO.AttrId)
	}
	if len(valueBO.Value) > 0 {
		db.Where("value = ?", valueBO.Value)
	}
	if len(valueBO.ValueArr) > 0 {
		db.Where("value in ?", valueBO.ValueArr)
	}
	if len(valueBO.StartTime) > 0 {
		db.Where("create_time = ?", valueBO.StartTime)
	}
	if len(valueBO.EndTime) > 0 {
		db.Where("create_time = ?", valueBO.EndTime)
	}
}

func (m *AttrValueMapper) InsertCtx(tx *gorm.DB, attrVal entity.AttrValueEntity) (attrCategoryId int64, err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#InsertCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx = tx.Create(&attrVal)
	return attrVal.AttrValueId, tx.Error
}

func (m *AttrValueMapper) BatchInsertCtx(engin *gorm.DB, attrValArr []*entity.AttrValueEntity) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#BatchInsertCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	tx := engin.Create(&attrValArr)
	return tx.Error
}

func (m *AttrValueMapper) BatchUpdateCtx(tx *gorm.DB, arrValArr []entity.AttrValueEntity) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#BatchUpdateCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	if len(arrValArr) <= 0 {
		return nil
	}
	var attrArrId []int64
	for _, v := range arrValArr {
		attrArrId = append(attrArrId, v.AttrValueId)
	}
	tx = tx.Where("attr_value_id in ?", attrArrId).UpdateColumns(&arrValArr)
	return tx.Error
}

func (m *AttrValueMapper) DeleteCtxByAttrId(tx *gorm.DB, attrIdArr []int64) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#DeleteCtxByAttrId")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	attrEntity := entity.AttrValueEntity{}
	tx = tx.Where("attr_id in ?", attrIdArr).Delete(&attrEntity)
	return tx.Error
}

func (m *AttrValueMapper) DeleteCtx(engin *gorm.DB, attrValueId []int64) (err error) {
	// 监控
	_, span := mysql.StartSpan(m.ctx, "AttrValueMapper#DeleteCtx")
	defer func() {
		mysql.EndSpan(span, err)
	}()
	attrEntity := entity.AttrValueEntity{}
	engin = engin.Where("attr_value_id in ?", attrValueId).Delete(&attrEntity)
	return engin.Error
}
